﻿using TimerJobServer.Common;
using log4net;
using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TimerJobServer
{
    /// <summary>
    /// 定时服务
    /// </summary>
    public class QuartzJobServer
    {
        private readonly ILog logger = LogManager.GetLogger(typeof(QuartzJobServer));

        public static List<QuarzJobInfo> Jobs = null;
        public static IScheduler sche = null;
        //配置文件路径
        private string configPath = AppDomain.CurrentDomain.BaseDirectory + "\\Config\\QuartzJobServer.json";
        //配置文件
        private static JSONConfig<List<QuarzJobInfo>> config;

        public QuartzJobServer()
        {
            config = new JSONConfig<List<QuarzJobInfo>>(configPath);
            sche = new StdSchedulerFactory().GetScheduler();
            sche.Start();
        }

        /// <summary>
        /// 执行当前任务
        /// </summary>
        /// <param name="quarzJobInfo"></param>
        public static void ExeJob(QuarzJobInfo quarzJobInfo)
        {
            QuartzJob job = new QuartzJob();
            job.ExeJob(quarzJobInfo);
        }

        /// <summary>
        /// 添加任务
        /// </summary>
        /// <param name="quarzJobInfo"></param>
        public static void  AddJob (QuarzJobInfo quarzJobInfo)
        {
            //如果名称存在则不添加
            if (Jobs.Where(o=>o.ID==quarzJobInfo.ID).Count()>0)
            {
                return;
            }

            if (Jobs!=null)
            {
                Jobs.Add(quarzJobInfo);
                config.Save();//保存配置文件
                Sche();//重新加载任务
            }
        }

        /// <summary>
        /// 删除任务
        /// </summary>
        /// <param name="quarzJobInfo"></param>
        public static void RemoveJob(QuarzJobInfo quarzJobInfo)
        {
            if (Jobs != null)
            {
                var job = Jobs.Where(o => o.ID == quarzJobInfo.ID).FirstOrDefault();
                if (job!=null)
                {
                    Jobs.Remove(job);
                    config.Save();//保存配置文件
                    Sche();//重新加载任务
                }
            }
        }

        /// <summary>
        /// 更新任务
        /// </summary>
        /// <param name="quarzJobInfo"></param>
        public static void UpdateJob(QuarzJobInfo quarzJobInfo)
        {
            if (Jobs != null)
            {
                var job = Jobs.Where(o => o.ID == quarzJobInfo.ID).FirstOrDefault();
                if (job != null)
                {
                    job.Name = quarzJobInfo.Name;
                    job.ClassFullName = quarzJobInfo.ClassFullName;
                    job.MethodName = quarzJobInfo.MethodName;
                    job.Cron = quarzJobInfo.Cron;
                    job.Enable = quarzJobInfo.Enable;
                    job.FullPath = quarzJobInfo.FullPath;
                    job.JobType = quarzJobInfo.JobType;
                    job.Args = quarzJobInfo.Args;
                    job.HttpHeaderDic = quarzJobInfo.HttpHeaderDic;
                    job.HttpPostDate = quarzJobInfo.HttpPostDate;
                    job.HttpURL = quarzJobInfo.HttpURL;
                    config.Save();//保存配置文件
                    Sche();//重新加载任务
                }
            }
        }


        /// <summary>
        /// 启用列表中服务
        /// </summary>
        /// <param name="quarzJobInfo"></param>
        public static void EnableJobs(List<QuarzJobInfo> quarzJobInfolist)
        {
            if (Jobs != null && quarzJobInfolist!=null)
            {
                foreach (var item in Jobs)
                {
                    if (quarzJobInfolist.Where(o => o.ID == item.ID).FirstOrDefault() != null)
                    {
                        item.Enable = true;
                    }
                }
                config.Save();//保存配置文件
                Sche();//重新加载任务
            }
        }

        /// <summary>
        /// 禁用列表中服务
        /// </summary>
        /// <param name="quarzJobInfo"></param>
        public static void DisableJobs(List<QuarzJobInfo> quarzJobInfolist)
        {
            if (Jobs != null && quarzJobInfolist != null)
            {
                foreach (var item in Jobs)
                {
                    if (quarzJobInfolist.Where(o => o.ID == item.ID).FirstOrDefault() != null)
                    {
                        item.Enable = false;
                    }
                }
                config.Save();//保存配置文件
                Sche();//重新加载任务
            }
        }

        internal static void Sche()
        {
            //清空任务
            sche.Clear();
            Jobs.ForEach(i =>
            {
                if (i.Enable)
                {
                    JobDataMap map = new JobDataMap();
                    map.Add("QuarzJobInfo", i);
                    IJobDetail job = JobBuilder.Create<QuartzJob>()
                        .UsingJobData(map)
                        .WithIdentity(i.ID, i.ID)
                        .Build();

                    ICronTrigger tri = (ICronTrigger)TriggerBuilder.Create()
                        .StartNow()
                        .WithIdentity("tri_" + i.ID, "tri_" + i.ID)
                        .WithCronSchedule(i.Cron)
                        .Build();
                    sche.ScheduleJob(job, tri);
                }
            });
        }

        /// <summary>
        /// 启动服务
        /// </summary>
        public void Start()
        {
            try
            {
                //服务启动
                logger.Info("定时任务启动");
                //WriteLog("服务:【" + srvName + "】将要启动了...");
                Jobs = config.Default;
                //if (!config.IsFileExists)
                //{
                //    Jobs.Add(new QuarzJobInfo() {
                //        ID = Guid.NewGuid().ToString("N"),
                //        Cron = "",
                //        Name = "测试任务"
                //    });
                //    config.Save();
                //}
                logger.Info("读取配置文件!");
                Sche();
                logger.Info("定时任务启动完成!");
            }
            catch (Exception ex)
            {
                logger.Fatal(ex.ToString());
            }
        }



        /// <summary>
        /// 停止功能
        /// </summary>
        public void Stop()
        {
            sche.Shutdown();
        }
    }
}
